<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>Tank Level Object</title>
  <script type="text/javascript" src="../../highlight.pack.js"></script>
  <script type="text/javascript" src="../../highlightCode.js"></script>
  <link href='../../highlight.css' rel='stylesheet' />
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script src="../../d3.v4.min.js"></script>


</head>
<body style='padding:10px;font-family:arial'>
<center>
<h4>Tank Level Object</h4>
<div style='width:90%;background-color:gainsboro;text-align:justify;padding:10px;border-radius:6px;'>
This is a configurable tank level object showing the 0 to maximum span values on the y-axis.
The level transitions smoothly during value changes, using D3 version 4. Also includes set point (dashed line) value, plus orange-to-red min/max alarm zones on the levelBar.
The levelBar flashes if values fall within the min/max alarm warning zones.
</div>
<table><tr>
<td>
<div style="padding:10px;width:500px;text-align:left">



<p></p><center>
<button onClick=changeHotWater()>Hot Water</button>
<button onClick=changeEthyleneGlycol()>Ethylene Glycol</button>
<button onClick=changeMapleSyrup()>Maple Syrup</button>
 <br>
Click button for a simulated change in the tank levels</center >
<p></p>
<b>Configuring The Tank Level:</b><br />
 buildTankLevel(id, title, units,max, levelBarColor, faceColor, minAlert, maxAlert, setPoint, initialValue, scale, transX, transY)
<br>
<br>

1.)  id - your ID for the tank level  <br>
2.) title - shown in tank level  <br>
3.) units - units of measurement<br>
5.) max - maximum value number range<br>
6.) levelBarColor - border enclosing the numbers  <br>
7.) faceColor - the background color <br>
8.) minAlert (optional) -  minimum alarm warning  value<br>

9.) maxAlert (optional) -  maximum alarm warning value<br>
10.) setPoint (optional) - setpoint of the control loop<br>

11.) initialValue - value first shown in the levelBar<br>
12.) scale - size the tank level (default size 300x400 px.)<br>

13.) transX - locate tank level upper-left x <br>
14.) transY - locate tank level  upper-left y <br>

</div>
</td>
<td>
<div id="svgDiv" style='width:400px;height:400px;'>
<svg id=mySVG width=400 height=400 overflow="visible">

</svg>
</div>

</td>
</tr></table>
  <br />SVG Source:
  <div id=svgSourceDiv style=overflow:auto;width:100%;height:1px;text-align:left; /></div>
  Javascript:
  <div id=jsCodeDiv style=overflow:auto;width:100%;text-align:left; /></div><p></p>
</center>
<script id=myScript>
//======================TANK LEVEL OBJECT========================================
function buildTankLevel(id,title,units,max,levelBarColor,faceColor,minAlert,maxAlert,setPoint,initialValue,scale,transX,transY)
{
    //---default size---
    var tankLevelWidth=300
    var tankLevelHeight=400

    var  TankLevel=d3.select("#mySVG").append("g")
    .attr("id",id)
    var tankLevelRect=TankLevel.append("rect")
    .attr("width",tankLevelWidth)
    .attr("height",tankLevelHeight)
    .attr("fill",faceColor)
    .attr("rx","55")
    .attr("ry","55")
    .attr("stroke","black")
    .attr("stroke-width",1)

    var myTitle=TankLevel.append("text")
    .text(title)
    .attr("x",tankLevelWidth/2)
    .attr("dy","1.5em")
    .attr("font-family","arial")
    .attr("font-size","25")
    .attr("font-weight","bold")
    .attr("text-anchor","middle")

    var myUnits=TankLevel.append("text")
    .attr("id","unitsText"+id)
    .text(initialValue+" "+units)
    .attr("x",tankLevelWidth/2)
    .attr("y",tankLevelHeight)
    .attr("dy","-.75em")
    .attr("font-family","arial")
    .attr("font-size","25")
    .attr("text-anchor","middle")


    var leftPadding=50
    var rightPadding=20
    var topPadding=50
    var botPadding=50

    var levelBarHeight=tankLevelHeight-topPadding-botPadding
    var levelBarWidth=tankLevelWidth-leftPadding-rightPadding
    var minMaxSpan=max

    //---bgRect
    TankLevel.append("rect")
    .attr("id", "levelBarBgRect")
    .attr("y", topPadding )
    .attr("x", leftPadding )
    .attr("width", levelBarWidth )
    .attr("fill", "gainsboro")
    .attr("height",levelBarHeight);

    var yBar = d3.scaleLinear()
    .range([0, levelBarHeight]);

    yBar.domain([max, 0])

    var pxPerValHt=levelBarHeight/minMaxSpan
    var initValueY=levelBarHeight-pxPerValHt*initialValue+topPadding

    TankLevel.append("rect")
    .attr("id", "levelBarRect"+id)
    .attr("fill", levelBarColor)
    .attr("opacity", "1")
    .attr("x", leftPadding)
    .attr("width", levelBarWidth)
    .attr("y", levelBarHeight+topPadding )
    .attr("height", 0 )
    .transition().duration(800)
    .attr("height", levelBarHeight-initValueY+topPadding )
    .attr("y", initValueY  )

    var defs=TankLevel.append("defs")
    var alarmXindent=60
    //----alarm----------------------------
    if(maxAlert)
    {
        var warningMax=defs.append("linearGradient")
        .attr("id","warningMax"+name)
        .attr("x1","84%")
        .attr("y1","24%")
        .attr("x2","82%")
        .attr("y2","72%")
        warningMax.append("stop")
        .attr("offset","0%")
        .attr("stop-color","#FF0000")
        .attr("stop-opacity","1")
        warningMax.append("stop")
        .attr("offset","100%")
        .attr("stop-color","#FFA500")
        .attr("stop-opacity","1")
        .attr("stop-offset","100%")

        var maxAlarmHeight=levelBarHeight-pxPerValHt*maxAlert

        TankLevel.append("rect")
        .attr("id","maxErrorRect")
        .attr("x",leftPadding+alarmXindent)
        .attr("y",topPadding)
        .attr("width",levelBarWidth-alarmXindent*2)
        .attr("height",maxAlarmHeight)
        .attr("stroke","none")
        .attr("fill","url(#warningMax)")
    }

    if(minAlert)
    {
        var warningMin=defs.append("linearGradient")
        .attr("id","warningMin"+name)
        .attr("x1","84%")
        .attr("y1","24%")
        .attr("x2","82%")
        .attr("y2","72%")
        warningMin.append("stop")
        .attr("offset","0%")
        .attr("stop-color","#FFA500")
        .attr("stop-opacity","1")
        .attr("stop-offset","0%")
        warningMin.append("stop")
        .attr("offset","100%")
        .attr("stop-color","#FF0000")
        .attr("stop-opacity","1")

        var minAlarmHeight=pxPerValHt*minAlert
        TankLevel.append("rect")
        .attr("id","minErrorRect")
        .attr("x",leftPadding+alarmXindent)
        .attr("y",topPadding+levelBarHeight-minAlarmHeight)
        .attr("width",levelBarWidth-alarmXindent*2)
        .attr("height",minAlarmHeight)
        .attr("stroke","none")
        .attr("fill","url(#warningMin)")
    }

    //-----------setpoint line------------
    if(setPoint)
    {
        var setPointY=levelBarHeight-pxPerValHt*setPoint+topPadding

        var dash=levelBarWidth/15

        TankLevel.append("line")
        .attr("id", "lineSP")
        .attr("x1",leftPadding)
        .attr("y1", setPointY)
        .attr("x2", leftPadding+levelBarWidth)
        .attr("y2", setPointY)
        .attr("stroke", "lime")
        .attr("stroke-width", 4)
        .attr("stroke-dasharray", dash+","+dash)
    }

    // add the y Axis
    TankLevel.append("g")
    .style("font-size",18)
    .attr("transform", "translate("+leftPadding+"," + topPadding + ")")
    .call(d3.axisLeft(yBar));

    TankLevel.attr("transform", "translate("+transX+" "+transY+")scale("+scale+")")

}


//---onload---
function placeTankLevels()
{
    // buildTankLevel(id,title,units,max,levelBarColor,faceColor,minAlert,maxAlert,setPoint,initialValue,scale,transX,transY)
  buildTankLevel("levelHotWater","Water Storage Tank","K Gallons",120,"black","violet",35,105,88,75,.3,100,30)
  buildTankLevel("levelEthyleneGlycol","Ethylene Glycol","K Liters",220,"black","skyblue",70,200,120,170,.4,200,100)
  buildTankLevel("levelMapleSyrup","Maple Syrup","\u0025",100,"black","#d2691e",8,95,75,50,.5,20,200)
}


var HotWaterWarning //---alarm interval---
//---button---
function changeHotWater()
{
    var max=120
    var topPadding=50
    var botPadding=50
    var tankLevelHeight=400
    var levelBarHeight=tankLevelHeight-topPadding-botPadding
    var pxPerValHt=levelBarHeight/max

    var hwValue=Math.floor(Math.random() * 100) + 20
    var valueY=levelBarHeight-pxPerValHt*hwValue+topPadding

    var units="K Gallons"
    d3.select("#unitsTextlevelHotWater")
    .text(hwValue+" "+units)

    var levelBar=d3.select("#levelBarRectlevelHotWater")
    var currentHeight=levelBar.attr("height")

    levelBar.attr("height", currentHeight )
    .transition().duration(800)
    .attr("height", levelBarHeight-valueY+topPadding )
    .attr("y", valueY  )

    //---Alarm Flash---
    var minAlert=35
    var maxAlert=105

    if(hwValue<=minAlert)
        if(!HotWaterWarning)
            HotWaterWarning=setInterval(warningHotWaterFlash,500)

    if(hwValue>=maxAlert)
        if(!HotWaterWarning)
            HotWaterWarning=setInterval(warningHotWaterFlash,500)

    if(hwValue>minAlert&&hwValue<maxAlert&&HotWaterWarning)
    {
        window.clearInterval(HotWaterWarning)
        levelBarRectlevelHotWater.setAttribute("opacity",1)
        HotWaterWarning=null
    }

}
var EthyleneGlycolWarning //---alarm interval---
//---button---
function changeEthyleneGlycol()
{
    var max=220
    var topPadding=50
    var botPadding=50
    var tankLevelHeight=400
    var levelBarHeight=tankLevelHeight-topPadding-botPadding
    var pxPerValHt=levelBarHeight/max

    var egValue=Math.floor(Math.random() * 180) + 40
    var valueY=levelBarHeight-pxPerValHt*egValue+topPadding

    var units="K Liters"
    d3.select("#unitsTextlevelEthyleneGlycol")
    .text(egValue+" "+units)

    var levelBar=d3.select("#levelBarRectlevelEthyleneGlycol")
    var currentHeight=levelBar.attr("height")

    levelBar.attr("height", currentHeight )
    .transition().duration(800)
    .attr("height", levelBarHeight-valueY+topPadding )
    .attr("y", valueY  )

    //---Alarm Flash---
    var minAlert=70
    var maxAlert=200

    if(egValue<=minAlert)
        if(!EthyleneGlycolWarning)
            EthyleneGlycolWarning=setInterval(warningEthyleneGlycolFlash,500)

    if(egValue>=maxAlert)
        if(!EthyleneGlycolWarning)
            EthyleneGlycolWarning=setInterval(warningEthyleneGlycolFlash,500)

    if(egValue>minAlert&&egValue<maxAlert&&EthyleneGlycolWarning)
    {
        window.clearInterval(EthyleneGlycolWarning)
        levelBarRectlevelEthyleneGlycol.setAttribute("opacity",1)
        EthyleneGlycolWarning=null
    }

}

var MapleSyrupWarning //---alarm interval---
//---button---
function changeMapleSyrup()
{
    var max=100
    var topPadding=50
    var botPadding=50
    var tankLevelHeight=400
    var levelBarHeight=tankLevelHeight-topPadding-botPadding
    var pxPerValHt=levelBarHeight/max

    var msValue=Math.floor(Math.random() * 90) + 10
    var valueY=levelBarHeight-pxPerValHt*msValue+topPadding

    var units="\u0025"
    d3.select("#unitsTextlevelMapleSyrup")
    .text(msValue+" "+units)

    var levelBar=d3.select("#levelBarRectlevelMapleSyrup")
    var currentHeight=levelBar.attr("height")

    levelBar.attr("height", currentHeight )
    .transition().duration(800)
    .attr("height", levelBarHeight-valueY+topPadding )
    .attr("y", valueY  )

    //---Alarm Flash---
    var minAlert=8
    var maxAlert=95

    if(msValue<=minAlert)
        if(!MapleSyrupWarning)
            MapleSyrupWarning=setInterval(warningMapleSyrupFlash,500)

    if(msValue>=maxAlert)
        if(!MapleSyrupWarning)
            MapleSyrupWarning=setInterval(warningMapleSyrupFlash,500)

    if(msValue>minAlert&&msValue<maxAlert&&MapleSyrupWarning)
    {
        window.clearInterval(MapleSyrupWarning)
        levelBarRectlevelMapleSyrup.setAttribute("opacity",1)
        MapleSyrupWarning=null
    }

}


//---alarm zone flash---
//---value into min/max alarm band----
function warningHotWaterFlash()
{
    if(+levelBarRectlevelHotWater.getAttribute("opacity")==1)
      levelBarRectlevelHotWater.setAttribute("opacity",.5)
     else
      levelBarRectlevelHotWater.setAttribute("opacity",1)
}
function warningEthyleneGlycolFlash()
{
    if(+levelBarRectlevelEthyleneGlycol.getAttribute("opacity")==1)
      levelBarRectlevelEthyleneGlycol.setAttribute("opacity",.5)
     else
      levelBarRectlevelEthyleneGlycol.setAttribute("opacity",1)
}
function warningMapleSyrupFlash()
{
    if(+levelBarRectlevelMapleSyrup.getAttribute("opacity")==1)
      levelBarRectlevelMapleSyrup.setAttribute("opacity",.5)
     else
      levelBarRectlevelMapleSyrup.setAttribute("opacity",1)
}

</script>
<script>
document.addEventListener("onload",init(),false)
function init()
{
   placeTankLevels()
   	showSourceSVG()
	showSourceJS()

}


</script>
<script>
  /*
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
  ga('create', 'UA-88028738-1', 'auto');
  ga('send', 'pageview');
 */

</script>
</body>

</html>